#include "esfera.h"
#include <math.h>


Esfera::Esfera(Color *cor,Vector *posicao,double kAmbiente,double kDifusa, double kEspecular,int nShing,double raio):Object(cor,posicao,kAmbiente,kDifusa,kEspecular,nShing),raio(raio) {
	this->raio = raio;
}

Esfera::Esfera( Vector *posicao, double raio):Object() {
	this->posicao = posicao;
	this->raio = raio;
}

Esfera::~Esfera(){
	
}

Vector* Esfera::vetorNormal(Ray *raio) {
	/*
	double a, b, c, delta, t1, t2, raiz;
	Vector *orientacao = raio->getDirecao();
	Vector *posicao = raio->getPosicao();
	Vector *p;
	Vector *pc;
	Vector *n;
	
	a = orientacao->produtoEscalar(orientacao); // a = ||V|| ao quadrado
	pc = posicao->subtracao(this->getPosicao()); // (Po - C)
	b = 2 * (orientacao->produtoEscalar( pc )); // 2*(V * (Po - C))
	c = pc->produtoEscalar(pc) - pow(this->raio, 2); // ||Po  - C|| ao quadrado - r ao quadrado
	
	delta = pow( b, 2) - 4*a*c;
	if (delta >= 0){ // intersectou a esfera  
		raiz = sqrt(delta);
		t1 = ((-b) + raiz )/(2 * a);
		t2 = ((-b) - raiz )/(2 * a);
		
		if (t1 >= 0 ){
			if( t2 >= 0 ){ // entao pega o menor deles
				if( t1 >= t2){
					p = posicao->soma(orientacao->multiplicacao(t2));
				} else {
					p = posicao->soma(orientacao->multiplicacao(t1));
				}
			} else {
				p = posicao->soma(orientacao->multiplicacao(t1));
			}			
		} else {
			if (t2 >= 0){
				p = posicao->soma(orientacao->multiplicacao(t2));
			} else {
				return NULL;
			}
		}

		n = p->subtracao(this->getPosicao()); // N = (P - C) / (||P - C||)
		n = n->vetorUnitario();
		return n;

	} else {
		return NULL;
	}*/
}

bool Esfera::testarColisao(Ray *raio){
	/*double a, b, c, delta, raiz, t1, t2;
	Vector* orientacao = raio->getDirecao();
	Vector* posicao = raio->getPosicao();

	a = orientacao->produtoEscalar(orientacao); // a = ||V|| ao quadrado
	Vector* pc = posicao->subtracao(this->getPosicao()); // (Po - C)
	b = 2 * (orientacao->produtoEscalar( pc )); // 2*(V * (Po - C))
	c = pc->produtoEscalar(pc) - pow(this->raio, 2); // ||Po  - C|| ao quadrado - r ao quadrado
	
	delta = pow( b, 2) - 4*a*c;
	if (delta >= 0){
		raiz = sqrt(delta);
		t1 = ((-b) + raiz )/(2 * a);
		t2 = ((-b) - raiz )/(2 * a);
		
		if((t1 < 0 ) && (t2 < 0)){
			return false;
		} else {
			return true;
		}

	} else {
		return false;
	}
	 */
	//sim o raytracing deve testar se este objeto tem possibilidade de colisao
	return true;
}

Intersect* Esfera::intersecsao(Ray *raio) {
	
	double a, b, c, delta, t1, t2, raiz, t;
	Vector *orientacao = raio->getDirecao();
	Vector *posicao = raio->getPosicao();
	Vector *p;
	Vector *pc;
	Vector *n;
	
	a = orientacao->produtoEscalar(orientacao); // a = ||V|| ao quadrado
	pc = posicao->subtracao(this->getPosicao()); // (Po - C)
	b = 2 * (orientacao->produtoEscalar( pc )); // 2*(V * (Po - C))
	c = pc->produtoEscalar(pc) - pow(this->raio, 2); // ||Po  - C|| ao quadrado - r ao quadrado
	
	delta = pow( b, 2) - 4*a*c;
	
	if (delta >= 0){ // intersectou a esfera  
		
		raiz = sqrt(delta);
		t1 = ((-b) + raiz )/(2 * a);
		t2 = ((-b) - raiz )/(2 * a);
				
		if (t1 >= 0 ){
			if( t2 >= 0 ){ // entao pega o menor deles
				if( t1 >= t2){
					p = posicao->soma(orientacao->multiplicacao(t2));
					t = t2;
				} else {
					p = posicao->soma(orientacao->multiplicacao(t1));
					t = t1;
				}
			} else {
				p = posicao->soma(orientacao->multiplicacao(t1));
				t = t1;
			}			
		} else {
			if (t2 >= 0){
				p = posicao->soma(orientacao->multiplicacao(t2));
				t = t2;
			} else {
				return NULL;
			}
		}
		
		n = p->subtracao(this->getPosicao()); // N = (P - C) / (||P - C||)
		n = n->vetorUnitario();
		Intersect *intersecsao = new Intersect(p,n,t);
		return intersecsao;

	} else {
		
		return NULL;
	}
}
